package com.supermap;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.supermap.config.Config;

import javax.imageio.stream.FileImageInputStream;
import javax.net.ssl.*;
import java.io.*;
import java.security.KeyManagementException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author liqs
 * @version 1.0
 * @date 2020/8/6 11:21
 */
public class Utils {

    /**
     * 生成查询语句(根据索引对数据进行查询)
     * @param jsonObject   确定信息查询 eq. delete = 0, dataSetHash = "dataSetHash"
     * @param jsonRang    索引范围查询 xmin xmax ymin ymax
     * @return
     */
    public static String generateQuerySelectorWithAnd(JSONObject jsonObject, JSONArray jsonRang){
        // 第一步 根据查询的条件设置 selector 语句
        // 添加确定信息部分
        Set<String> keys = jsonObject.keySet();
        StringBuilder qureySelector = new StringBuilder();
        Boolean start = false;
        int count = 1;
        int total = keys.size();
        for(String key : keys){
            if(start){
                qureySelector.append(",");
//                qureySelector.append("\"");
            }
            qureySelector.append("{\"" );
            qureySelector.append(key);
            qureySelector.append("\":\"");
            qureySelector.append(jsonObject.getString(key));
            qureySelector.append("\"}" );

            start = true;
            count = count + 1;
        }
        // 根据输入的范围自己构造查询语句
        JSONArray jsonArray = generateIndexQuery(jsonRang);
        // 第二部分  构造索引   xmin xmax ymin ymax
        for(int i = 0; i < jsonArray.size(); i ++){
            JSONArray jsonArrayTmp = (JSONArray)jsonArray.get(i);
            qureySelector.append(",");
            qureySelector.append("{\"");
            qureySelector.append(jsonArrayTmp.get(0));
            qureySelector.append("\":{\"");
            qureySelector.append(jsonArrayTmp.get(1));
            qureySelector.append("\":\"");
            qureySelector.append(jsonArrayTmp.get(2));
            qureySelector.append("\"}}");
        }

        String selector0 = "{\"selector\":{\"$and\":[" + qureySelector.toString() + "]}}";

        // {"selector":{"$and":[{"dataSetHash":"6bff876faa82c51aee79068a68d4a814af8c304a0876a08c0e8fe16e5645fde4"},"{"delete":"0"},{"xmin":{"$gte":"115.375"}},{"xmax":{"$lte":"117.5"}},{"ymin":{"$gte":"39.416666666667"}},{"ymax":{"$lte":"41.083333333333"}}]}}
//        String selector1 = "{\"selector\":{\"$and\":[{\"test\":\"test\"},{\"xmin\":{\"$gte\":\"0.23\"}}]}}";
//        if (selector0.equals(selector1)){
//            System.out.println("");
//        }
        return selector0;
    }

    public static JSONArray generateIndexQuery(JSONArray jsonArray){

        JSONArray returnJsonArray = new JSONArray();

        JSONArray jsonXmin = new JSONArray();
        jsonXmin.add(Config.SM_LEFT);
        jsonXmin.add("$gte");
        jsonXmin.add(jsonArray.get(0));

        JSONArray jsonXmax = new JSONArray();
        jsonXmax.add(Config.SM_RIGHT);
        jsonXmax.add("$lte");
        jsonXmax.add(jsonArray.get(1));

        JSONArray jsonYmin = new JSONArray();
        jsonYmin.add(Config.SM_BOTTOM);
        jsonYmin.add("$gte");
        jsonYmin.add(jsonArray.get(2));

        JSONArray jsonYmax = new JSONArray();
//        jsonYmax.add("ymax");
        jsonYmax.add(Config.SM_TOP);
        jsonYmax.add("$lte");
        jsonYmax.add(jsonArray.get(3));

        returnJsonArray.add(jsonXmin);
        returnJsonArray.add(jsonXmax);
        returnJsonArray.add(jsonYmin);
        returnJsonArray.add(jsonYmax);

        return returnJsonArray;

    }

    /**
     * 生成查询语句（key value 形式）
     * @param jsonObject eq. delete = 0, dataSetHash = "dataSetHash"
     * @return
     */
    public static String generateQuerySelector(JSONObject jsonObject){

        Set<String> keys = jsonObject.keySet();
        StringBuilder qureySelector = new StringBuilder();
        Boolean start = false;
        int count = 1;
        int total = keys.size();
        qureySelector.append("{\"" );
        for(String key : keys){
            if(start){
                qureySelector.append(",");
                qureySelector.append("\"");
            }
            qureySelector.append(key);
            qureySelector.append("\":\"");
            qureySelector.append(jsonObject.getString(key));
            if(count <= total){
                qureySelector.append("\"");
            }
            start = true;
            count = count + 1;
        }
        qureySelector.append("}");
        String selector = "{\"selector\":" + qureySelector.toString() + "}";
        return selector;
    }

    public static byte[] fileToByte(String path){
        byte[] data = null;
        FileImageInputStream input = null;
        try {
            input = new FileImageInputStream(new File(path));
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            byte[] buf = new byte[1024];
            int numBytesRead = 0;
            while ((numBytesRead = input.read(buf)) != -1) {
                output.write(buf, 0, numBytesRead);
            }
            data = output.toByteArray();
            output.close();
            input.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return data;
    }

    /**
     * 读取文件为 byte[]
     * @param file
     * @return
     */
    public static byte[] getFileBytes(String file) {
        byte[] data = null;
        try {
            File f = new File(file);
            int length = (int) f.length();
            data = new byte[length];
            FileInputStream in = new FileInputStream(f);
            in.read(data);
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return data;

    }

    /**
     * 时间戳转为时间  1584963081  -------------->   "2020-03-23 19:31:21"
     */
    public static String stampToDate(int time){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time_Date = sdf.format(new Date(time * 1000L));
//        String time_Date = sdf.format(new Date(time));
        return time_Date;
    }

    /*
     * 将时间转换为时间戳  "2020-03-23 19:31:21"  -------------->   1584963081
     */
    public static String dateToStamp(String time){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String stamp = "";
        if (!"".equals(time)) {//时间不为空
            try {
                stamp = String.valueOf(sdf.parse(time).getTime()/1000  + 8 * 3600);
            } catch (Exception e) {
                System.out.println("参数为空！");
            }
        }else {    //时间为空
            long current_time = System.currentTimeMillis();  //获取当前时间
            stamp = String.valueOf(current_time/1000 + 8 * 3600);
        }
        return stamp;
    }

    public static String stampToData(Date timestamp){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");    //格式化规则
        //获得你要处理的时间 Date型
        String strDate= sdf.format(timestamp); //格式化成yyyy-MM-dd格式的时间字符串
//        Date newDate = null;
//        try {
//            newDate = sdf.parse(strDate);
//        } catch (ParseException e) {
//            e.printStackTrace();
//        }
//        java.sql.Date resultDate = new java.sql.Date(newDate.getTime());//最后转换成 java.sql.Date类型数据就可以了 注意：最开始时间数据类型是 java.util.Date类型
        return strDate;
    }

    /*
     * 将时间转换为时间戳  "2020-03-23 19:31:21"  -------------->   1584963081
     */
    public static String dateToStampAddLittle(String time){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String stamp = "";
        if (!"".equals(time)) {//时间不为空
            try {
                stamp = String.valueOf(sdf.parse(time).getTime()/1000);
            } catch (Exception e) {
                System.out.println("参数为空！");
            }
        }else {    //时间为空
            long current_time = System.currentTimeMillis();  //获取当前时间
            stamp = String.valueOf(current_time/1000 + 1);
        }
        return stamp;
    }

    /** 将 json 保存为json文件 */
    public boolean createJsonFile(Object jsonData) {
        String content = JSON.toJSONString(jsonData, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteDateUseDateFormat);
        // 标记文件生成是否成功
        boolean flag = true;
        // 生成json格式文件
        try {
            // 保证创建一个新文件
            File file = new File("E:\\neworg.json");
            if (!file.getParentFile().exists()) { // 如果父目录不存在，创建父目录
                file.getParentFile().mkdirs();
            }
            if (file.exists()) { // 如果已存在,删除旧文件
                file.delete();
            }
            file.createNewFile();
            // 将格式化后的字符串写入文件
            Writer write = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
            write.write(content);
            write.flush();
            write.close();
        } catch (Exception e) {
            flag = false;
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 合并 byte[][]
     * @param bt1
     * @param bt2
     * @param count
     * @return
     */
    public static byte[][] byteMerger(byte[][] bt1, byte[][] bt2, int count){
        byte[][] byteMerger = null;
        if(count == 0){
            byteMerger = bt2;
        }else{
            byteMerger = new byte[bt1.length+bt2.length][];
            System.arraycopy(bt1, 0, byteMerger, 0, bt1.length);
            System.arraycopy(bt2, 0, byteMerger, bt1.length, bt2.length);
        }
        return byteMerger;
    }

    /**
     * 对 String 进行 base64 编码
     * @param string
     * @return
     */
    public static String base64Encoder(String string){
        Base64.Encoder encoder = Base64.getEncoder();
        byte[] bytes = new byte[0];
        try {
            bytes = string.getBytes("utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String encoding = encoder.encodeToString(bytes);
        return encoding;
    }

    public static String base64Decoder(String string){
        Base64.Decoder decoder = Base64.getDecoder();
        String decoding = null;
        try {
            decoding = new String(decoder.decode(string), "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return decoding;
    }

    /**
     * 将一维数组转为二维数组
     * @param onedouble
     * @return
     */
    public static byte[][] TwoArry(byte[] onedouble){
        byte[][] arr = new byte[1][onedouble.length];
        for (int i = 0; i < onedouble.length; i++) {
            arr[0][i] = onedouble[i];
        }
        return arr;
    }

    /**
     * 将二维数组保存为本地文件
     */
    public static void saveByteToLocalFile(byte[][] results, String localFilePath, String fileName, String count){

        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        for (byte[] resultByte : results) {
            try {
                File dir = new File(localFilePath);
                if(!dir.exists() && !dir.isDirectory()){//判断文件目录是否存在
                    dir.mkdirs();
                }
                file = new File(localFilePath + File.separator + fileName + count);
                fos = new FileOutputStream(file);
                bos = new BufferedOutputStream(fos);
                bos.write(resultByte);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            bos.close();
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String readJsonFile(String fileName) {
        String jsonStr = "";
        try {
            File jsonFile = new File(fileName);
            FileReader fileReader = new FileReader(jsonFile);

            Reader reader = new InputStreamReader(new FileInputStream(jsonFile),"utf-8");
            int ch = 0;
            StringBuffer sb = new StringBuffer();
            while ((ch = reader.read()) != -1) {
                sb.append((char) ch);
            }
            fileReader.close();
            reader.close();
            jsonStr = sb.toString();
            return jsonStr;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static byte[] byteMerger(byte[] bt1, byte[] bt2){
        byte[] bt3 = null;
        bt3 = new byte[bt1.length+bt2.length];
        System.arraycopy(bt1, 0, bt3, 0, bt1.length);
        System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length);
        return bt3;
    }

    /**
     * 将字节数组分割
     * @param bytes
     * @param size
     * @return
     */
    public static byte[][] byteSpilt(byte[] bytes, int size){
        double splitLength = Double.parseDouble(size + "");
        int arrayLength = (int) Math.ceil(bytes.length / splitLength);

        byte[][] result = new byte[arrayLength][];
        int from, to;
        for (int i = 0; i < arrayLength; i++) {

            from = (int) (i * splitLength);
            to = (int) (from + splitLength);
            if (to > bytes.length)
                to = bytes.length;
            result[i] = Arrays.copyOfRange(bytes, from, to);
        }
        return result;
    }

    public static UUID getUuid() {
        UUID uuid = UUID.randomUUID();
        return uuid;
    }

    public static String getSHA256(String str) {
        if (str == null) {
            return null;}
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
            messageDigest.reset();
            messageDigest.update(str.getBytes());
            return byte2Hex(messageDigest.digest());
        } catch (Exception e) {
            throw new RuntimeException(e);}
    }

    // StringBuffer 建立的字符串可以进行修改，并且不产生新的未使用对象
    private static String byte2Hex(byte[] bytes) {
        StringBuffer stringBuffer = new StringBuffer();
        String temp = null;
        for (int i = 0; i < bytes.length; i++) {
            temp = Integer.toHexString(bytes[i] & 0xFF);
            if (temp.length() == 1) {
                stringBuffer.append("0");
            }
            stringBuffer.append(temp);
        }
        return stringBuffer.toString();
    }


    // https与http不同的是，https加密，需要验证证书，而http不需要(加上这个之后访问就可以直接使用IP地址访问)
    public static void disableSslVerification() {
        try
        {
            // Create a trust manager that does not validate certificate chains
            TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                public void checkClientTrusted(X509Certificate[] certs, String authType) {
                }
                public void checkServerTrusted(X509Certificate[] certs, String authType) {
                }
            }
            };

            // Install the all-trusting trust manager
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

            // Create all-trusting host name verifier
            HostnameVerifier allHostsValid = new HostnameVerifier() {
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            };

            // Install the all-trusting host verifier
            HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
    }

}
